#include "UIBuf.h"

CUIBuf::CUIBuf()
{
    this->_size = { 0,0 };
    this->_visible = false;
    this->_zIndex = 0;
    this->_dfn = CUIBuf::DFN++;
    cfcgl::uibufs.push_back(this);
    _pos = { 0,0 };
}

void CUIBuf::Show(bool visible)
{
    if (this->_visible == visible)return;
    this->_visible = visible;
    this->ForceUpdate();
}

void CUIBuf::SetPos(Coord pos)
{
    bool tmp = this->_visible;
    this->Show(false);
    this->_pos = pos;
    this->Show(tmp);
}

Pixel& CUIBuf::at(Coord pos)
{
    return this->_pxbuf[pos.X][pos.Y];
}

Pixel& CUIBuf::operator[](Coord pos)
{
    return this->_pxbuf[pos.X][pos.Y];
}

bool CUIBuf::operator>(const CUIBuf& b)
{
    return (this->_zIndex > b._zIndex) || (this->_zIndex == b._zIndex && this->_dfn > b._dfn);
}

bool CUIBuf::operator<(const CUIBuf& b)
{
    return (this->_zIndex < b._zIndex) || (this->_zIndex == b._zIndex && this->_dfn < b._dfn);
}

void CUIBuf::resize(Coord size)
{
    bool tmp = this->_visible;
    this->Show(false);
    this->_size = size;
    this->_pxbuf.resize(size.X);
    for (int i = 0; i < size.X; i++)
        this->_pxbuf[i].resize(size.Y);
    this->Show(tmp);
}

void CUIBuf::SetzIndex(size_t zIndex)
{
    if (this->_zIndex != zIndex)
    {
        this->_zIndex = zIndex;
        this->ForceUpdate();
    }
}

void CUIBuf::ForceUpdate()
{
    if (this->_visible)
    {
        for (Length i = this->_pos.X; i < this->_pos.X + this->_size.X; i++)
        {
            for (Length j = this->_pos.Y; j < this->_pos.Y + this->_size.Y; j++)
            {
                if (cfcgl::pxtop[i][j] == nullptr || *this > *cfcgl::pxtop[i][j])
                {
                    cfcgl::pxtop[i][j] = this;
                    cfcgl::screen[i][j] = this->at({ Length(i - this->_pos.X),Length(j - this->_pos.Y) });
                    cfcgl::ScreenUpdatePending = true;
                }
                else if (this == cfcgl::pxtop[i][j])
                {
                    cfcgl::UpdatePixel({ i,j });
                }
            }
        }
    }
    else
    {
        for (Length i = this->_pos.X; i < this->_pos.X + this->_size.X; i++)
        {
            for (Length j = this->_pos.Y; j < this->_pos.Y + this->_size.Y; j++)
            {
                if (this == cfcgl::pxtop[i][j])
                {
                    cfcgl::UpdatePixel({ i,j });
                }
            }
        }
    }

}
void CUIBuf::Update()
{
    for (Length i = this->_pos.X; i < this->_pos.X + this->_size.X; i++)
    {
        for (Length j = this->_pos.Y; j < this->_pos.Y + this->_size.Y; j++)
        {
            if (this == cfcgl::pxtop[i][j])
            {
                cfcgl::screen[i][j] = this->at({ Length(i - this->_pos.X),Length(j - this->_pos.Y) });
            }
        }
    }
}

CUIBuf::~CUIBuf()
{
    cfcgl::uibufs.erase(std::remove(cfcgl::uibufs.begin(), cfcgl::uibufs.end(), this), cfcgl::uibufs.end());
}



size_t CUIBuf::DFN;